home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP06.ZIP / CHAP06 / POLYLINE / POLYLINE.CPP < prev    next >
C/C++ Source or Header  |  1993-04-22  |  13KB  |  580 lines

  1. /*
  2.  * POLYLINE.CPP
  3.  * Polyline Component Object Chapter 6
  4.  *
  5.  * Implementation of the CPolyline class that we expose as an
  6.  * OLE 2.0 component object.
  7.  *
  8.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Software Design Engineer
  11.  * Microsoft Systems Developer Relations
  12.  *
  13.  * Internet  :  kraigb@microsoft.com
  14.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  15.  */
  16.  
  17.  
  18. #include "polyline.h"
  19.  
  20.  
  21. /*
  22.  * CPolyline:CPolyline
  23.  * CPolyline::~CPolyline
  24.  *
  25.  * Constructor Parameters:
  26.  *  punkOuter       LPUNKNOWN of the controlling unknown.
  27.  *  pfnDestroy      LPFNDESTROYED to call when an object is destroyed.
  28.  *  hInst           HINSTANCE of the application we're in.
  29.  */
  30.  
  31. CPolyline::CPolyline(LPUNKNOWN punkOuter, LPFNDESTROYED pfnDestroy
  32.     , HINSTANCE hInst)
  33.     {
  34.     m_hWnd=NULL;
  35.     m_hInst=hInst;
  36.  
  37.     m_cRef=0;
  38.     m_punkOuter=punkOuter;
  39.     m_pfnDestroy=pfnDestroy;
  40.     m_fDirty=FALSE;
  41.  
  42.     m_pST=NULL;
  43.     m_cf =0;
  44.  
  45.     //CHAPTER6MOD
  46.     m_clsID=CLSID_Polyline6;
  47.     m_iID  =IID_IPolyline6;
  48.  
  49.     //NULL any contained interfaces initially.
  50.     m_pIPolyline        =NULL;
  51.     m_pIPersistStorage  =NULL;
  52.     m_pIDataObject      =NULL;
  53.     m_pIDataAdviseHolder=NULL;
  54.     m_pAdv              =NULL;
  55.  
  56.     //Initialize IDataObject::EnumFormatEtc arrays
  57.     m_cf=RegisterClipboardFormat(SZPOLYLINECLIPFORMAT);
  58.  
  59.     m_cfeGet=CFORMATETCGET;
  60.     m_cfeSet=CFORMATETCSET;
  61.  
  62.     SETDefFormatEtc(m_rgfeGet[0], m_cf, TYMED_HGLOBAL);
  63.     SETDefFormatEtc(m_rgfeGet[1], CF_METAFILEPICT, TYMED_MFPICT);
  64.     SETDefFormatEtc(m_rgfeGet[2], CF_BITMAP, TYMED_GDI);
  65.  
  66.     SETDefFormatEtc(m_rgfeSet[0], m_cf, TYMED_HGLOBAL);
  67.     //End CHAPTER6MOD
  68.     return;
  69.     }
  70.  
  71.  
  72. CPolyline::~CPolyline(void)
  73.     {
  74.     if (NULL!=m_pST)
  75.         delete m_pST;
  76.  
  77.     //Free our contained interfaces, delete those we own, Release others.
  78.     //CHAPTER6MOD
  79.     if (NULL!=m_pIDataAdviseHolder)
  80.         m_pIDataAdviseHolder->Release();
  81.  
  82.     if (NULL!=m_pIDataObject)
  83.         delete m_pIDataObject;
  84.     //End CHAPTER6MOD
  85.  
  86.     if (NULL!=m_pIPersistStorage)
  87.         delete m_pIPersistStorage;
  88.  
  89.     if (NULL!=m_pIPolyline)
  90.         delete m_pIPolyline;
  91.  
  92.     //Reverses the AddRef in ::SetAdvise
  93.     if (NULL!=m_pAdv)
  94.         m_pAdv->Release();
  95.  
  96.     return;
  97.     }
  98.  
  99.  
  100.  
  101.  
  102. /*
  103.  * CPolyline::FInit
  104.  *
  105.  * Purpose:
  106.  *  Performs any intiailization of a CPolyline that's prone to failure
  107.  *  that we also use internally before exposing the object outside
  108.  *  this DLL.
  109.  *
  110.  * Parameters:
  111.  *  None
  112.  *
  113.  * Return Value:
  114.  *  BOOL            TRUE if the function is successful, FALSE otherwise.
  115.  */
  116.  
  117. BOOL CPolyline::FInit(void)
  118.     {
  119.     LPUNKNOWN       pIUnknown=(LPUNKNOWN)this;
  120.  
  121.     if (NULL!=m_punkOuter)
  122.         pIUnknown=m_punkOuter;
  123.  
  124.     m_pST=new CStringTable(m_hInst);
  125.  
  126.     if (!m_pST->FInit(IDS_POLYLINEMIN, IDS_POLYLINEMAX))
  127.         return FALSE;
  128.  
  129.     //Allocate contained interfaces.
  130.     m_pIPolyline=new CImpIPolyline(this, pIUnknown);
  131.  
  132.     if (NULL==m_pIPolyline)
  133.         return FALSE;
  134.  
  135.     m_pIPersistStorage=new CImpIPersistStorage(this, pIUnknown);
  136.  
  137.     if (NULL==m_pIPersistStorage)
  138.         return FALSE;
  139.  
  140.     //CHAPTER6MOD
  141.     m_pIDataObject=new CImpIDataObject(this, pIUnknown);
  142.  
  143.     if (NULL==m_pIDataObject)
  144.         return FALSE;
  145.     //End CHAPTER6MOD
  146.  
  147.     return TRUE;
  148.     }
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156. /*
  157.  * CPolyline::QueryInterface
  158.  * CPolyline::AddRef
  159.  * CPolyline::Release
  160.  *
  161.  * Purpose:
  162.  *  IUnknown members for CPolyline object.
  163.  */
  164.  
  165. STDMETHODIMP CPolyline::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  166.     {
  167.     *ppv=NULL;
  168.  
  169.     /*
  170.      * The only calls we get here for IUnknown are either in a non-aggregated
  171.      * case or when we're created in an aggregation, so in either we always
  172.      * return our IUnknown for IID_IUnknown.
  173.      */
  174.     if (IsEqualIID(riid, IID_IUnknown))
  175.         *ppv=(LPVOID)this;
  176.  
  177.     //For anything else we return contained interfaces.
  178.     if (IsEqualIID(riid, m_iID))
  179.         *ppv=(LPVOID)m_pIPolyline;
  180.  
  181.     if (IsEqualIID(riid, IID_IPersist) || IsEqualIID(riid, IID_IPersistStorage))
  182.         *ppv=(LPVOID)m_pIPersistStorage;
  183.  
  184.     //CHAPTER6MOD
  185.     if (IsEqualIID(riid, IID_IDataObject))
  186.         *ppv=(LPVOID)m_pIDataObject;
  187.     //End CHAPTER6MOD
  188.  
  189.     //AddRef any interface we'll return.
  190.     if (NULL!=*ppv)
  191.         {
  192.         ((LPUNKNOWN)*ppv)->AddRef();
  193.         return NOERROR;
  194.         }
  195.  
  196.     return ResultFromScode(E_NOINTERFACE);
  197.     }
  198.  
  199.  
  200. STDMETHODIMP_(ULONG) CPolyline::AddRef(void)
  201.     {
  202.     return ++m_cRef;
  203.     }
  204.  
  205.  
  206. STDMETHODIMP_(ULONG) CPolyline::Release(void)
  207.     {
  208.     ULONG       cRefT;
  209.  
  210.     cRefT=--m_cRef;
  211.  
  212.     if (0==m_cRef)
  213.         delete this;
  214.  
  215.     return cRefT;
  216.     }
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224. /*
  225.  * CPolyline::RectConvertMappings
  226.  *
  227.  * Purpose:
  228.  *  Converts the contents of a rectangle from device (MM_TEXT) or
  229.  *  HIMETRIC to the other.
  230.  *
  231.  * Parameters:
  232.  *  pRect           LPRECT containing the rectangle to convert.
  233.  *  fToDevice       BOOL TRUE to convert from HIMETRIC to device,
  234.  *                  FALSE to convert device to HIMETRIC.
  235.  *
  236.  * Return Value:
  237.  *  None
  238.  */
  239.  
  240. void CPolyline::RectConvertMappings(LPRECT pRect, BOOL fToDevice)
  241.     {
  242.     HDC      hDC;
  243.     int      iLpx, iLpy;
  244.  
  245.     if (NULL==pRect)
  246.         return;
  247.  
  248.     hDC=GetDC(NULL);
  249.     iLpx=GetDeviceCaps(hDC, LOGPIXELSX);
  250.     iLpy=GetDeviceCaps(hDC, LOGPIXELSY);
  251.     ReleaseDC(NULL, hDC);
  252.  
  253.     if (fToDevice)
  254.         {
  255.         pRect->left=MulDiv(iLpx, pRect->left, HIMETRIC_PER_INCH);
  256.         pRect->top =MulDiv(iLpy, pRect->top , HIMETRIC_PER_INCH);
  257.  
  258.         pRect->right =MulDiv(iLpx, pRect->right,  HIMETRIC_PER_INCH);
  259.         pRect->bottom=MulDiv(iLpy, pRect->bottom, HIMETRIC_PER_INCH);
  260.  
  261.        #ifdef NEVER
  262.         /*
  263.          * In this conversion we may get situations where the top
  264.          * coordinate is larger than the bottom, which messes us up.
  265.          */
  266.         if (pRect->bottom < pRect->top)
  267.             {
  268.             iLpy=pRect->top;
  269.             pRect->top=pRect->bottom;
  270.             pRect->bottom=iLpy;
  271.             }
  272.        #endif
  273.         }
  274.     else
  275.         {
  276.         pRect->left=MulDiv(pRect->left, HIMETRIC_PER_INCH, iLpx);
  277.         pRect->top =MulDiv(pRect->top , HIMETRIC_PER_INCH, iLpy);
  278.  
  279.         pRect->right =MulDiv(pRect->right,  HIMETRIC_PER_INCH, iLpx);
  280.         pRect->bottom=MulDiv(pRect->bottom, HIMETRIC_PER_INCH, iLpy);
  281.         }
  282.  
  283.     return;
  284.     }
  285.  
  286.  
  287.  
  288.  
  289. //CHAPTER6MOD
  290. //Functions now internal due to IDataObject
  291.  
  292. /*
  293.  * CPolyline::DataSet
  294.  *
  295.  * Purpose:
  296.  *  Sets the current data in this Polyline to a given structure.
  297.  *
  298.  * Parameters:
  299.  *  pplIn           LPPOLYLINEDATA to initialize to.
  300.  *  fSizeToData     BOOL indicating if we're to size to the data or scale it.
  301.  *  fNotify         BOOL indicating if we're to send an advise on this change.
  302.  *
  303.  * Return Value:
  304.  *  HRESULT         NOERROR if successful, otherwise a POLYLINE_E_ value.
  305.  */
  306.  
  307. STDMETHODIMP CPolyline::DataSet(LPPOLYLINEDATA pplIn, BOOL fSizeToData
  308.     , BOOL fNotify)
  309.     {
  310.     RECT            rc;
  311.  
  312.     /*
  313.      * Copy the structure in pplIn and repaint to reflect the new point
  314.      * set.  Note that unlike the RectSet message, we do no scaling,
  315.      * assuming that the rect in the structure is appropriate for the data.
  316.      */
  317.  
  318.     if (NULL==pplIn)
  319.         return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
  320.  
  321.     //Preserve the old rectangle, then copy
  322.     rc=m_pl.rc;
  323.     m_pl=*pplIn;
  324.     m_fDirty=TRUE;
  325.  
  326.  
  327.     //CHAPTER6MOD
  328.     //Inform our parent of the data change
  329.     if (NULL!=m_pIDataAdviseHolder)
  330.         {
  331.         m_pIDataAdviseHolder->SendOnDataChange(m_pIDataObject
  332.             , DVASPECT_CONTENT, ADVF_NODATA);
  333.         }
  334.     //End CHAPTER6MOD
  335.  
  336.     /*
  337.      * If we're scaling the window to fit the data, then use
  338.      * RectSet passing our current rectangle as the new one.
  339.      * That makes sure that the data won't change but that the
  340.      * window is resized.
  341.      */
  342.  
  343.     if (fSizeToData)
  344.         {
  345.         POINT       pt;
  346.  
  347.         /*
  348.          * Get our